package cn.dengta.webapp.trade.model;

import java.math.BigDecimal;

public enum TradeTypeCore {
	/**
	 * 增加可用: 总额增加，可用增加，冻结不变
	 */
	ADD_ACTIVE("增加可用", "++0"),
	/**
	 * 扣除可用: 总额减少，可用减少，冻结不变
	 */
	DEDUCT_ACTIVE("扣除可用", "--0"),
	/**
	 * 解冻额度(冻结转可用): 总额不变，可用增加，冻结减少
	 */
	FROZEN_TO_ACTIVE("解冻额度", "0+-"),
	/**
	 * 增加冻结：总额增加，可用减少，冻结增加
	 */
	ADD_FROZEN("冻结额度", "+0+"),
	/**
	 * 冻结额度：总额不变，可用减少，冻结增加
	 */
	ACTIVE_TO_FROZEN("冻结额度", "0-+"),
	/**
	 * 扣除冻结额度: 总额减少，可用不变，冻结减少
	 */
	DEDUCT_FROZEN("扣除冻结额度", "-0-"),
	;

	/** 主播收益的积分核心交易类型 */
	public static final TradeTypeCore anchorIncomeCore = ADD_FROZEN;

	/** 交易操作符：<code>[ total, active, frozen ]</code> */
	public final char[] operators;
	final String label;
	final Flow flow;

	public static final char OP_ADD = '+';
	public static final char OP_SUBTRACT = '-';
	public static final char OP_NOOP = '0';

	TradeTypeCore(String label, String operators) {
		this.operators = operators.toCharArray();
		if (this.operators.length != 3) {
			throw new IllegalArgumentException("The expected length of operators is 3, but actually is " + this.operators.length);
		}
		this.label = label;
		this.flow = calcFlow(this.operators);
	}

	public String getLabel() {
		return label;
	}

	public static Integer calc(Integer source, char operator, Integer target) {
		switch (operator) {
			case OP_ADD:
				return source + target;
			case OP_SUBTRACT:
				return source - target;
			case OP_NOOP:
				return source;
			default:
				throw new UnsupportedOperationException("不支持的运算符：" + operator);
		}
	}

	public static BigDecimal calc(BigDecimal source, char operator, BigDecimal target) {
		switch (operator) {
			case OP_ADD:
				return source.add(target);
			case OP_SUBTRACT:
				return source.subtract(target);
			case OP_NOOP:
				return source;
			default:
				throw new UnsupportedOperationException("不支持的运算符：" + operator);
		}
	}

	/**
	 * 是否是消费交易（减少可用余额）
	 */
	public boolean isConsume() {
		return operators[1] == OP_SUBTRACT;
	}

	/**
	 * 是否是收益交易（增加可用余额）
	 */
	public boolean isIncome() {
		return operators[1] == OP_ADD;
	}

	/**
	 * 返回该交易类型的页面展示符号
	 *
	 * @return '+' 或 '0' 或 '-'
	 */
	public char getSign() {
		return operators[1];
	}

	public Flow getFlow() {
		return flow;
	}

	static Flow calcFlow(final char[] operators) {
		final char a = operators[1], f = operators[2];
		int aInt = a == OP_ADD ? 1 : (a == OP_SUBTRACT ? -1 : 0),
				fInt = f == OP_ADD ? 1 : (f == OP_SUBTRACT ? -1 : 0);
		int result = aInt + fInt;
		if (result > 0) {
			return Flow.INCOME;
		} else if (result < 0) {
			return Flow.CONSUME;
		}
		return Flow.NONE;
	}
}
